﻿#include "QCefUtilV8.h"


CefRefPtr<CefV8Value> CefValueToV8Value(CefValue* cefValue)
{
    CefRefPtr<CefV8Value> v8Value = CefV8Value::CreateNull();
    if (!cefValue)
    {
        return v8Value;
    }

    auto type = cefValue->GetType();
    switch (type)
    {
    case CefValueType::VTYPE_INVALID:
    {
        v8Value = CefV8Value::CreateUndefined();
    }
    break;
    case CefValueType::VTYPE_NULL:
    {
        v8Value = CefV8Value::CreateNull();
    }
    break;
    case CefValueType::VTYPE_BOOL:
    {
        auto v = cefValue->GetBool();
        v8Value = CefV8Value::CreateBool(v);
    }
    break;
    case CefValueType::VTYPE_INT:
    {
        auto v = cefValue->GetInt();
        v8Value = CefV8Value::CreateInt(v);
    }
    break;
    case CefValueType::VTYPE_DOUBLE:
    {
        auto v = cefValue->GetDouble();
        v8Value = CefV8Value::CreateDouble(v);
    } break;
    case CefValueType::VTYPE_STRING:
    {
        auto v = cefValue->GetString();
        v8Value = CefV8Value::CreateString(v);
    } break;
    case CefValueType::VTYPE_BINARY:
    {
        // TO-DO
        // currently not supported
    }
    break;
    case CefValueType::VTYPE_DICTIONARY:
    {
        auto cDict = cefValue->GetDictionary();
        CefDictionaryValue::KeyList cKeys;
        cDict->GetKeys(cKeys);
        v8Value = CefV8Value::CreateObject(nullptr, nullptr);
        for (auto& key : cKeys)
        {
            auto cVal = cDict->GetValue(key);
            auto v8Val = CefValueToV8Value(cVal.get());
            v8Value->SetValue(key, v8Val.get(), V8_PROPERTY_ATTRIBUTE_NONE);
        }
    }
    break;
    case CefValueType::VTYPE_LIST:
    {
        auto cList = cefValue->GetList();
        int cCount = static_cast<int>(cList->GetSize());
        v8Value = CefV8Value::CreateArray(static_cast<int>(cCount));
        for (int i = 0; i < cCount; i++)
        {
            auto cVal = cList->GetValue(i);
            auto v8Val = CefValueToV8Value(cVal.get());
            v8Value->SetValue(i, v8Val.get());
        }
    }
    break;
    default:
        break;
    }

    return v8Value;
}

CefRefPtr<CefValue> V8ValueToCefValue(CefV8Value* v8Value)
{
    CefRefPtr<CefValue> cefValue = CefValue::Create();
    if (!v8Value)
    {
        return cefValue;
    }

    if (v8Value->IsNull() || v8Value->IsUndefined())
    {
        cefValue->SetNull();
    }
    else if (v8Value->IsBool())
    {
        cefValue->SetBool(v8Value->GetBoolValue());
    }
    else if (v8Value->IsInt())
    {
        cefValue->SetInt(v8Value->GetIntValue());
    }
    else if (v8Value->IsUInt() || v8Value->IsDouble())
    {
        cefValue->SetDouble(v8Value->GetDoubleValue());
    }
    else if (v8Value->IsString())
    {
        cefValue->SetString(v8Value->GetStringValue());
    }
    else if (v8Value->IsArrayBuffer())
    {
        // TO-DO
        // currently not supported
    }
    else if (v8Value->IsArray())
    {
        auto s = v8Value->GetArrayLength();
        auto cefList = CefListValue::Create();
        for (int i = 0; i < s; i++)
        {
            auto v8Val = v8Value->GetValue(i);
            auto cefVal = V8ValueToCefValue(v8Val.get());
            cefList->SetValue(i, cefVal);
        }
        cefValue->SetList(cefList);
    }
    else if (v8Value->IsObject())
    {
        CefDictionaryValue::KeyList keys;
        v8Value->GetKeys(keys);
        auto cefDict = CefDictionaryValue::Create();
        for (auto& key : keys)
        {
            auto v8Val = v8Value->GetValue(key);
            auto cefVal = V8ValueToCefValue(v8Val.get());
            cefDict->SetValue(key, cefVal.get());
        }
        cefValue->SetDictionary(cefDict);
    }
    else
    {
        cefValue->SetNull();
    }

    return cefValue;
}

